﻿using Heroius.Extension;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;

namespace WinPathMan
{
    public static class Utility
    {
        public static IEnumerable<PathEntity> GetPaths(EnvironmentVariableTarget tar = EnvironmentVariableTarget.User)
        {
            return GetEnvironmentPath(tar).Split(';').Select(p => new PathEntity(p));
        }

        public static void SetPaths(IEnumerable<string> paths, EnvironmentVariableTarget tar)
        {
            SetEnvironmentPath(paths.Merge(";"), tar);
        }

        public static string GetRegistKey(EnvironmentVariableTarget tar)
        {
            string RegKey = string.Empty;
            switch (tar)
            {
                case EnvironmentVariableTarget.User:
                    RegKey = "HKEY_CURRENT_USER\\Environment";
                    break;
                default:
                case EnvironmentVariableTarget.Machine:
                    RegKey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";
                    break;
            }
            return RegKey;
        }

        public static string GetEnvironmentPath(EnvironmentVariableTarget tar)
        {
            var reg = GetRegistKey(tar);
            return Registry.GetValue(reg, "Path", "").ToString();
        }

        public static void SetEnvironmentPath(string val, EnvironmentVariableTarget tar)
        {
            var reg = GetRegistKey(tar);
            Registry.SetValue(reg, "Path", val);
            ChangeReg();
        }


        const int WM_SETTINGCHANGE = 0x001A;
        const int HWND_BROADCAST = 0xffff;

        public enum SendMessageTimeoutFlags : uint
        {
            SMTO_NORMAL = 0x0000,
            SMTO_BLOCK = 0x0001,
            SMTO_ABORTIFHUNG = 0x0002,
            SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
        }

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessageTimeout(
        IntPtr windowHandle,
        uint Msg,
        IntPtr wParam,
        IntPtr lParam,
        SendMessageTimeoutFlags flags,
        uint timeout,
        out IntPtr result
        );

        public static void ChangeReg()
        {
            //通知所有打开的程序注册表已修改
            SendMessageTimeout(new IntPtr(HWND_BROADCAST), WM_SETTINGCHANGE, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out IntPtr _);
        }
    }
}
